package com.ssm.common.utils;


import com.ssm.modules.dao.ILogDao;
import com.ssm.modules.entity.Log;
import com.ssm.modules.entity.User;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Map;


public class LogUtils {


    public static void saveLog(HttpServletRequest request, Object handler, Exception ex, String title, ILogDao logDao) {
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute("user");
        if (user != null && user.getId() != 0){
            Map<String, String[]> paramMap = request.getParameterMap();
            StringBuilder params = new StringBuilder();
            for (Map.Entry<String, String[]> param : ((Map<String, String[]>)paramMap).entrySet()){
                params.append(("".equals(params.toString()) ? "" : "&") + param.getKey() + "=");
                String paramValue = (param.getValue() != null && param.getValue().length > 0 ? param.getValue()[0] : "");
                params.append(param.getKey().equals("password") ? "" : paramValue);
            }
            Log log = new Log();
            log.setTitle(title);
            log.setType(ex == null ? Log.TYPE_ACCESS : Log.TYPE_EXCEPTION);
            log.setRemoteAddr(getRemoteAddr(request));
            log.setUserAgent(request.getHeader("user-agent"));
            log.setRequestUri(request.getRequestURI());
            log.setParams(params.toString());
            log.setMethod(request.getMethod());
            log.setUser(user);
            // 异步保存日志
            new SaveLogThread(log, handler, ex, logDao).start();
        }
    }

    /**
     * 获得用户远程地址
     */
    public static String getRemoteAddr(HttpServletRequest request){
        String remoteAddr = request.getHeader("X-Real-IP");
        if (isNotBlank(remoteAddr)) {
            remoteAddr = request.getHeader("X-Forwarded-For");
        }else if (isNotBlank(remoteAddr)) {
            remoteAddr = request.getHeader("Proxy-Client-IP");
        }else if (isNotBlank(remoteAddr)) {
            remoteAddr = request.getHeader("WL-Proxy-Client-IP");
        }
        return remoteAddr != null ? remoteAddr : request.getRemoteAddr();
    }

    public static boolean isNotBlank(CharSequence cs) {
        return !isBlank(cs);
    }

    public static boolean isBlank(CharSequence cs) {
        int strLen;
        if (cs != null && (strLen = cs.length()) != 0) {
            for(int i = 0; i < strLen; ++i) {
                if (!Character.isWhitespace(cs.charAt(i))) {
                    return false;
                }
            }

            return true;
        } else {
            return true;
        }
    }


    /**
     * 保存日志线程
     */
    public static class SaveLogThread extends Thread{

        private Log log;
        private Object handler;
        private Exception ex;
        private ILogDao logDao;

        public SaveLogThread(Log log, Object handler, Exception ex, ILogDao logDao){
            super(SaveLogThread.class.getSimpleName());
            this.log = log;
            this.handler = handler;
            this.ex = ex;
            this.logDao = logDao;
        }

        @Override
        public void run() {
            // 如果有异常，设置异常信息
            if(ex != null) {
                log.setException(ex.toString());
            }
            // 保存日志信息
            logDao.insert(log);
        }
    }

}
